﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SdmxMl.Common;
using SdmxMl.Structure;
using SdmxMl.Manager;
using SdmxMl.UC;

namespace SdmxMl.Panels
{
    public partial class DlgChangeParent : Form
    {
        public IHierarchyManage ihManage { get; set; }
        private TreeNode nodeParent;
        bool expandedFull;

        public Artefact Clone { get; set; }


        public DlgChangeParent(ISdmxHierarchyListItem it, Artefact a, IHierarchyManage fl)
        {
            InitializeComponent();
            
            buttonApply.Enabled = buttonSave.Enabled = buttonSetParent.Enabled = false;
            if (a is Artefact)
            {
                buttonSetParent.Enabled = true;
                toolStripStatusInfo.Text = "Select desired Parent in tree and set it.";
                SmManager sm = new SmManager();
                Clone = sm.CloneArtefact(a);
                if (Clone != null)
                    FillTree();                
            }
        }

        private void FillTree()
        {
            expandedFull = false;
            treeViewItems.Nodes.Clear();
            nodeParent = null;
            TreeNode ndRoot = new TreeNode("Root");
            Clone.FillNode(ndRoot);
            treeViewItems.BeginUpdate();
            treeViewItems.Nodes.Add(ndRoot.FirstNode.FirstNode);

            ihManage = treeViewItems.Nodes[0].Tag as IHierarchyManage;

            treeViewItems.Nodes[0].Expand();
            treeViewItems.Nodes[0].EnsureVisible();
            treeViewItems.EndUpdate();
        }

        #region Buttons Event

        private void buttonSetParent_Click(object sender, EventArgs e)
        {
            if (treeViewItems.SelectedNode != null)
            {
                nodeParent = treeViewItems.SelectedNode;
                nodeParent.ImageIndex = nodeParent.SelectedImageIndex = 2;
                buttonSetParent.Enabled = false;
                buttonSave.Enabled = false;
                buttonApply.Enabled = true;
                toolStripStatusInfo.Text = "Right-click on desired new children, then press Apply.";
            }

        }

        private bool IsChildNode(TreeNode nodeTarget, TreeNode node)
        {
            if (node == nodeTarget)
                return true;
            foreach (TreeNode n in node.Nodes)
                if (IsChildNode(nodeTarget, n))
                    return true;
            return false;
        }


        private void treeViewItems_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            TreeNode selNode = e.Node;
            if (e.Button == MouseButtons.Right &&
                nodeParent != null && selNode != null && selNode != nodeParent && selNode != treeViewItems.Nodes[0])
            {
                if (selNode.ImageIndex == 3)
                    selNode.ImageIndex = selNode.SelectedImageIndex = 0;
                else
                {
                    // Cannot redefine a parent of target parent as its child
                    if (IsChildNode(nodeParent, selNode) == false)
                        selNode.ImageIndex = selNode.SelectedImageIndex = 3;
                }
            }
        }

        private void buttonApply_Click(object sender, EventArgs e)
        {
            if (treeViewItems.Nodes.Count > 0)
            {
                // Refresh parent for all selected items, then redraw tree
                string parentId = string.Empty;
                ISdmxHierarchyListItem item = nodeParent.Tag as ISdmxHierarchyListItem;
                if (item != null)
                    parentId = item.Id;

                UpdateParent(treeViewItems.Nodes[0], parentId);

                FillTree();
                buttonSave.Enabled = true;
                buttonApply.Enabled = false;
                buttonSetParent.Enabled = true;
                toolStripStatusInfo.Text = "Restart with other Parent or Save.";

            }
        }

        private void buttonSave_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.OK;
            this.Close();
        }


        private void UpdateParent(TreeNode node, string parentId)
        {
            if (node.ImageIndex == 3)
            {
                ISdmxHierarchyListItem item = node.Tag as ISdmxHierarchyListItem;
                if (item != null)
                {
                    // Real hierarchical collection
                    if (ihManage is FlatHierarchicalList)
                    {
                        ihManage.HasHierarchy = true;
                        item.Parent = parentId;
                    }
                    else
                    {
                        ihManage.RedefineParent(item, null, nodeParent.Tag);
                    }
                }

            }
            foreach (TreeNode n in node.Nodes)
                UpdateParent(n, parentId);

        }

        private void toolStripSplitButtonExpand_ButtonClick(object sender, EventArgs e)
        {
            if (expandedFull)
            {
                treeViewItems.CollapseAll();
                expandedFull = false;
            }
            else
            {
                treeViewItems.ExpandAll();
                expandedFull = true;
            }
        }

        #endregion

        #region Move Node

        void tv_AfterNodeMove(object sender, MoveableTreeView.AfterNodeMoveEventArgs e)
        {
            if (e != null && e.MovedNode != null)
            {
                ISdmxHierarchyListItem item = e.MovedNode.Tag as ISdmxHierarchyListItem;
                if (item != null)
                {
                    if (ihManage != null)
                    {
                        // All items on same level (even if hierarchy is exprimed)
                        if (ihManage is FlatHierarchicalList)
                        {
                            FlatHierarchicalList fhl = ihManage as FlatHierarchicalList;
                            if (e.NewIndex > 0)
                            {
                                ISdmxHierarchyListItem prevItem = e.MovedNode.Parent.Nodes[e.NewIndex - 1].Tag as ISdmxHierarchyListItem;
                                fhl.Remove(item);
                                int ndx = fhl.IndexOf(prevItem);
                                fhl.Insert(ndx + 1, item);

                            }
                            else
                            {
                                // Previous can be a parent item. If none, we assume start position for moved one
                                ISdmxHierarchyListItem prevItem = e.MovedNode.Parent.Tag as ISdmxHierarchyListItem;

                                fhl.Remove(item);
                                int ndx = -1;
                                if (prevItem != null)
                                    ndx = fhl.IndexOf(prevItem);
                                fhl.Insert(ndx + 1, item);
                            }
                        }
                        // Real hierarchical collection
                        else if (ihManage is CategoryList)
                        {
                            // The parent meta attribute collection is to be rearanged
                            Category catParent = e.MovedNode.Parent.Tag as Category;
                            CategoryList list = null;
                            if (catParent == null)
                                list = ihManage as CategoryList;
                            else
                                list = catParent.CategoryList;

                            Category catMoved = e.MovedNode.Tag as Category;
                            list.Remove(catMoved);
                            list.Insert(e.NewIndex, catMoved);
                        }
                    }
                }
            }       
        }

        void tv_BeforeNodeMove(object sender, MoveableTreeView.BeforeNodeMoveEventArgs e)
        {
            e.Cancel = true;
            if (treeViewItems.SelectedNode != null)
            {
                if (treeViewItems.SelectedNode.Tag is ISdmxHierarchyListItem)
                    e.Cancel = false;
            }
        }


        #endregion //Move node



    }
}
